Skip to main content

시스템 콜

시스템 콜이란?​

시스템 콜(system call)은 운영체제의 커널이 제공하는 서비스에 대해, 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스 이다. 보통 C나 C++과 같은 고급 언어로 작성된 프로그램들은 직접 시스템 호출을 사용할 수 없기 때문에 고급 API를 통해 시스템 호출에 접근하게 하는 방법이다.

즉, 응용프로그램에서 운영체제에게 어떠한 기능을 수행해달라고 하는 하나의 수단 이다.

시스템 콜에 대한 이해​

  1. 사용자 프로세스가 시스템 콜을 요청하면 커널로 제어가 넘어옴 (사용자모드 -> 커널모드)
  2. 커널은 내부적으로 각각의 시스템 콜을 구분하기 위해 기능별로 고유번호를 할당하고 그 번호에 해당하는 제어루틴을 커널 내부에 정의
  3. 커널은 요청받은 시스템 콜에 대응하는 기능번호를 확인
  4. 커널은 그 번호에 맞는 서비스 루틴을 호출
  5. 서비스 루틴을 모두 처리하고 나면 커널 모드에서 사용자 모드로 다시 전환

​

시스템 콜의 유형​

프로세스 제어(Process Control)

  • 끝내기(end), 중지(abort)
  • 적재(load), 실행(execute)
  • 프로세스 생성(create process)
  • 프로세스 속성 획득과 설정(get process attribute and set process attribute)
  • 시간 대기(wait time)
  • 사건 대기(wait event)
  • 사건을 알림(signal event)
  • 메모리 할당 및 해제 : malloc, free

파일 조작(File Manipulation)

  • 파일 생성(create file), 파일 삭제(delete file)
  • 열기(open), 닫기(close)
  • 읽기(read), 쓰기(write), 위치 변경(reposition)
  • 파일 속성 획득 및 설정(get file attribute and set file attribute)

장치 관리(Devide Management)

  • 장치를 요구(request devices), 장치를 방출(release device)
  • 읽기, 쓰기, 위치 변경
  • 장치 속성 획득, 장치 속성 설정
  • 장치의 논리적 부착(attach) 또는 분리(detach)

정보 유지(Information Maintenance)

  • 시간과 날짜의 설정과 획득(time)
  • 시스템 데이터의 설정과 획득(date)
  • 프로세스 파일, 장치 속성의 획득 및 설정

통신(Communication)

  • 통신 연결의 생성, 제거
  • 메시지의 송신, 수신
  • 상태 정보 전달
  • 원격 장치의 부착 및 분리

보안(protection)

  • Permission 획득
  • Permission 설정

​

시스템 콜 처리과정 - fork​

fork

위 그림은 가장 대표적인 시스템 콜 예시인 fork() 함수의 시스템 콜 처리과정입니다.

  1. user process에서 fork() 시스템 콜을 호출

  2. C라이브러리(libc.a)에서 fork의 시스템 콜 고유번호인 '2'를 레지스터에 저장하고 0x80 인터럽트를 발생시킴

    (int 0x80에서 int는 interrupt를 뜻하는 명령어. 인터럽트가 발생했으므로 User Mode-> Kerner Mode로 전환)

  3. 이후 커널은 IDT(Interrupt Descriptor Table)에서 0x80주소에 있는 system_call()을 호출

  4. system_call()함수에서는 호출된 시스템 콜 번호와 레지스터들을 스택에 저장하고 검증

  5. 과정 4에서 스택에 옮겨놓은 값을 기반으로 sys_call_table에서 sys_fork()함수 탐색 및 호출

  6. 함수 종료 후에는 사용자 프로세스로 리턴 및 Kerner Mode -> User Mode로 전환

​

시스템 콜 처리과정 - open​

syscall1

위 그림은 open() 시스템 콜을 사용한 예시이다.

자세한 과정은 위의 fork()와 유사하다. 대략적인 과정은 위 그림을 참고하면 도움이 될 것 같다.

​

시스템 콜의 매개변수 전달​

필요한 기능이나 시스템의 환경에 따라 시스템 콜이 발생할 때 좀 더 많은 정보가 필요할 수 있다.

이러한 정보가 담긴 매개변수를 운영체제에 전달하기 위한 3가지의 방법이 존재한다.

  1. 레지스터 이용 : 가장 간단한 방법으로, 매개변수를 레지스터에 넣어 전달한다. 단, 레지스터 개수보다 매개변수의 개수가 더 많을 수도 있다.
  2. 메모리 블록 이용 : 매개변수를 메모리 내 블록에 저장하고, 블록의 주소를 레지스터에 매개변수로 넣어 전달한다. ( Linux와 Solaris가 사용하는 방법 )
  3. 스택 이용 : 프로그램에 의해 매개변수가 스택에 넣어지고(push), 운영체제에 의해 꺼내어진다(pop off).
tip

운영체제는 블록이나 스택 방법을 선호하는데 , 이는 전달되는 매개변수 개수나 용량이 제한 받지 않기 때문이다.

syscall_memory

위 그림은 2의 과정인 메모리 블록을 이용한 방법을 나타낸 그림이다.

​

예상되는 면접 질문​

  • 사용자가 시스템 콜을 호출했을 때 일어나는 과정에 대해 설명해주세요
  • 시스템 콜이란 무엇이며, 왜 사용하나요?
  • 시스템 콜의 매개변수 전달 방법중 레지스터를 이용하는 방법이 있습니다. 이 방법의 단점이 있을까요?

​

참고자료​

기여자​


HongEunho

📦